package com.fowo.api.common.util;

import lombok.experimental.UtilityClass;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@UtilityClass
public class StringUtils {

    /**
     * 将 Pascal 命名转换为下划线命名
     */
    public String pascalToUnderline(String param) {
        if(param != null) {
            int len = param.length();
            StringBuilder sb = new StringBuilder(len * 2);
            for(int i = 0; i < len; i++) {
                char c = param.charAt(i);
                if (Character.isUpperCase(c) && i != 0) {
                    sb.append("_");
                }
                sb.append(Character.toLowerCase(c));
            }
            return sb.toString();
        }
        return null;
    }

    /**
     * 将下划线命名转换为 Pascal 命名
     */
    public String underlineToPascal(String param) {
        if(param != null) {
            int len = param.length();
            StringBuilder sb = new StringBuilder(len);
            boolean toUpper = false;
            for(int i = 0; i < len; i++) {
                char c = param.charAt(i);
                if (i == 0 || c == '_') {
                    toUpper = true;
                }
                else if (toUpper) {
                    sb.append(Character.toUpperCase(c));
                    toUpper = false;
                }
                else {
                    sb.append(c);
                }
            }
            return sb.toString();
        }
        return null;
    }

    public static String parentPath(String toPath) {
        String[] parts = toPath.split("/");
        List<String> noEmptyParts = new ArrayList<>();
        for (String part : parts) {
            if(part != null && part.length() > 0) {
                noEmptyParts.add(part);
            }
        }
        if (noEmptyParts.isEmpty()) {
            return null;
        }
        noEmptyParts.remove(noEmptyParts.size() - 1);
        String parent = ListUtils.join("/", noEmptyParts);
        if (toPath.startsWith("/")) {
            parent = "/" + parent;
        }
        return parent;
    }

    /**
     * 从多个字符串参数中返回第一个非空字符串
     */
    public static String firstHasText(String ...strings) {
        for(String str : strings) {
            if (org.springframework.util.StringUtils.hasText(str)) {
                return str;
            }
        }
        return null;
    }

    /**
     * 获取 HTML 中的纯文本内容
     * @param html HTML 内容
     * @return
     */
    public static String getTextByHtml(String html) {
        if (html == null) {
            return null;
        }
        return html.replaceAll("<[^>]+>", "");
    }

    /**
     * 按最大长度缩减显示文本
     * @param string 要显示的文本
     * @param maxLength 最大长度
     */
    public static String ellipsis(String string, int maxLength) {
        if (string.length() > maxLength) {
            return string.substring(0, maxLength - 3) + "...";
        }
        return string;
    }

    private static final Pattern TPL_PATTERN = Pattern.compile("\\$\\{([^}]*)}");
    /**
     * 字符串通用模版参数替换，识别字符串中的 ${something} 格式, 然后给 replacer 替换为需要的值
     * @param string 源字符串
     * @param replacer 参数替换回调
     * @return 替换后的字符串
     */
    public static String templateReplace(String string, Function<String, String> replacer) {
        Matcher matcher = TPL_PATTERN.matcher(string);
        StringBuilder sb = new StringBuilder();
        while(matcher.find()) {
            String replacement = replacer.apply(matcher.group(1));
            matcher.appendReplacement(sb, replacement);
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
